package timing.ukulele.portal.service;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import timing.ukulele.common.data.ResponseCode;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.data.portal.view.UserVO;
import timing.ukulele.persistence.service.BaseService;
import timing.ukulele.portal.mapper.SysUserMapper;
import timing.ukulele.portal.persistent.SysUser;
import timing.ukulele.share.UserLabelEnum;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Service
public class SysUserService extends BaseService<SysUserMapper, SysUser> {

    /**
     * 根据用户名查询用户
     *
     * @param username 用户名
     * @return SysUser 用户信息
     */
    public SysUser getUserByUserName(String username) {
        return this.lambdaQuery().eq(SysUser::getUsername, username).one();
    }

    /**
     * 根据电话号码查询用户
     *
     * @param phone 电话号码
     * @return SysUser 用户信息
     */
    public SysUser getUserByPhone(String phone) {
        return this.lambdaQuery().eq(SysUser::getPhone, phone).one();
    }

    /**
     * 根据电话号码或用户名查询用户信息
     *
     * @param phoneOrName 电话号码
     * @return 用户信息
     */
    public SysUser getUserByPhoneOrName(String phoneOrName) {
        return this.lambdaQuery().eq(SysUser::getUsername, phoneOrName).or().eq(SysUser::getPhone, phoneOrName).one();
    }

    /**
     * 多条件查询用信息
     *
     * @param map 用户条件，key须与表属性对应
     * @return 用户列表
     */
    public List<SysUser> getUserByParam(Map<String, Object> map) {
        return super.listByMap(map);
    }

    public List<SysUser> getUserListByPhoneOrName(String phoneOrName) {
        return this.lambdaQuery().like(SysUser::getName, phoneOrName).or().like(SysUser::getPhone, phoneOrName).list();
    }

    public IPage<UserVO> getPage(String username, String phone, String label, String name, String email, Boolean deleted, int current, int size) {
        Page<SysUser> page = new Page<>(current, size);
        LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(username))
            query.likeRight(SysUser::getUsername, username);
        if (StringUtils.hasText(phone))
            query.likeRight(SysUser::getPhone, phone);
        if (StringUtils.hasText(label))
            query.eq(SysUser::getLabel, label);
        if (StringUtils.hasText(name))
            query.likeRight(SysUser::getName, name);
        if (StringUtils.hasText(email))
            query.likeRight(SysUser::getEmail, email);
        if (deleted != null)
            query.eq(SysUser::getDeleted, deleted);
        query.orderByDesc(SysUser::getId);
        IPage<SysUser> iPage = this.getBaseMapper().selectPage(page, query);
        Page<UserVO> voPage = new Page<>(current, size);
        if (iPage != null && !CollectionUtils.isEmpty(iPage.getRecords())) {
            List<UserVO> voList = new ArrayList<>(iPage.getRecords().size());
            iPage.getRecords().forEach(po -> {
                UserVO vo = new UserVO();
                BeanUtils.copyProperties(po, vo);
                po.setPassword(null);
                voList.add(vo);
            });
            voPage.setTotal(iPage.getTotal());
            voPage.setRecords(voList);
        }
        return voPage;
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseData<String> registerUser(UserVO user, Boolean sendMessage) {
        List<SysUser> existUsers = this.lambdaQuery().or().eq(SysUser::getUsername, user.getUsername()).or().eq(SysUser::getPhone, user.getPhone()).list();
        if (!CollectionUtils.isEmpty(existUsers)) {
            if (existUsers.stream().anyMatch(item -> item.getUsername().equalsIgnoreCase(user.getUsername())))
                return new ResponseData<>(ResponseCode.ERROR.getCode(), "该用户名已被使用，请更换");
            if (existUsers.stream().anyMatch(item -> item.getPhone().equalsIgnoreCase(user.getPhone())))
                return new ResponseData<>(ResponseCode.ERROR.getCode(), "该手机号已被使用，请更换");
        }
        SysUser userPO = new SysUser();
        BeanUtils.copyProperties(user, userPO);
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 34, 6, 2);
        String password = captcha.getCode();
        // 密码
        userPO.setPassword(new BCryptPasswordEncoder(6).encode(password));
        userPO.setCreateBy(user.getUsername());
        Random random = new Random();
        int s = random.nextInt(6) % (6 - 1 + 1) + 1;
        // 头像
        userPO.setAvatar("/static/tmp/img/" + s + ".png");
        // 注册用户初始为user角色
        userPO.setLabel(UserLabelEnum.USER.getLabel());
        this.save(userPO);
        // 没有设置成功
//        ResponseData<Boolean> roleResponse = roleFeignFacade.userRegistered(userPO.getId(), userPO.getUsername());
//        if (roleResponse == null || roleResponse.getData() == null || !roleResponse.getData()) {
//            this.removeById(userPO.getId());
//            return new ResponseData<>(ResponseCode.ERROR, "角色设置失败");
//        }
//        if (StringUtils.hasText(user.getPlatId()) && null != user.getPlat()) {
//            SysThirdPartyUserVO thirdPartyUser = new SysThirdPartyUserVO();
//            thirdPartyUser.setDeleted(Boolean.FALSE);
//            thirdPartyUser.setCreateTime(new Date());
//            thirdPartyUser.setPlatId(user.getPlatId());
//            if (StringUtils.hasText(user.getUnionId())) {
//                thirdPartyUser.setUnionId(user.getUnionId());
//            }
//            thirdPartyUser.setPlatSource(user.getPlat());
//            thirdPartyUser.setUserId(userPO.getId());
//            thirdPartyUser.setUsername(userPO.getUsername());
//            this.thirdPartyUserService.bindThirdUser(thirdPartyUser);
//        }
//        if (sendMessage) {
//            Map<String, Object> message = new HashMap<>(8);
//            message.put("id", userPO.getId());
//            message.put("account", userPO.getUsername());
//            message.put("password", password);
//            rabbitTemplate.convertAndSend(PASSWORD_CHANNEL, PASSWORD_ROUTING, message);
//        }
        return new ResponseData<>(ResponseCode.SUCCESS.getCode(), "注册成功", userPO.getId() + "");
    }

    public ResponseData<String> registerUserByThird(UserVO user) {
        // 验证
        List<SysUser> existUsers = this.lambdaQuery().or()
                .eq(SysUser::getUsername, user.getUsername()).or()
                .eq(SysUser::getPhone, user.getPhone()).list();
        if (!CollectionUtils.isEmpty(existUsers)) {
            if (existUsers.stream().anyMatch(item -> item.getUsername().equalsIgnoreCase(user.getUsername()))) {
                return new ResponseData<>(ResponseCode.ERROR.getCode(), "该用户名已被使用，请更换");
            }
            if (existUsers.stream().anyMatch(item -> item.getPhone().equalsIgnoreCase(user.getPhone()))) {
                return new ResponseData<>(ResponseCode.ERROR.getCode(), "该手机号已被使用，请更换");
            }
        }
        // 添加
        SysUser userPO = new SysUser();
        BeanUtils.copyProperties(user, userPO);
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 34, 6, 2);
        String password = captcha.getCode();
        // 密码
        userPO.setPassword(new BCryptPasswordEncoder(6).encode(password));
        userPO.setCreateBy(user.getUsername());
        Random random = new Random();
        int s = random.nextInt(6) % (6 - 1 + 1) + 1;
        // 头像
        userPO.setAvatar("/static/tmp/img/" + s + ".png");
        // 注册用户初始为user角色
        userPO.setLabel(UserLabelEnum.USER.getLabel());
        this.save(userPO);
        // TODO 发送消息，告知用户登录账号以及初始密码
        return ResponseData.success("注册成功", userPO.getId() + "");
    }

}
